package com.yifeng.repo.base.utils.converter.date;

import com.google.common.base.Strings;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 日期工具类
 * Created by daibing on 2017/12/16.
 * @deprecated ：兼容代码，要求使用 com.yifeng.repo.base.utils.converter.DateHelper
 */
public class DateHelper {
    public static final int ONE_DAY_MILLIS = 1000 * 3600 * 24;
    public static final String TIME_ZONE = "GMT";
    public static final String TIME_FORMAT = "HH:mm:ss";

    public static final String DAY_FORMAT = "yyyy-MM-dd";
    public static final String DAY_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DAY_TIME_PRO_FORMAT = "yyyy-MM-dd HH:mm:ss.S";

    public static final String TIDY_DAY_FORMAT = "yyyyMMdd";
    public static final String TIDY_DAY_TIME_FORMAT = "yyyyMMddHHmmss";
    public static final String TIDY_DAY_TIME_PRO_FORMAT = "yyyyMMddHHmmssSSS";

    public static final String RFC_2616_DAY_TIME_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
    public static final String RFC_2616_DAY_TIME_PRO_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";

    public static final String ISO_8601_DAY_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    public static final String ISO_8601_DAY_MINUTE_FORMAT = "yyyy-MM-dd'T'HH:mm'Z'";
    public static final String ISO_8601_DAY_TIME = "yyyyMMdd'T'HHmmss'Z'";
    public static final String ISO_8601_DAY_TIME_PRO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'";

    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DAY_TIME_FORMAT);
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DAY_FORMAT);
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(TIME_FORMAT);

    public static String getDateTime(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DATE_TIME_FORMATTER);
    }

    public static String getDate(LocalDate dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DATE_FORMATTER);
    }

    public static String getTime(LocalTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(TIME_FORMATTER);
    }

    public static LocalDateTime parseDateTime(String strLocalDateTime) {
        if (Strings.isNullOrEmpty(strLocalDateTime)) {
            return null;
        }
        return LocalDateTime.parse(strLocalDateTime, DATE_TIME_FORMATTER);
    }

    public static LocalDate parseDate(String strLocalDate) {
        if (Strings.isNullOrEmpty(strLocalDate)) {
            return null;
        }
        return LocalDate.parse(strLocalDate, DATE_FORMATTER);
    }

    public static LocalTime parseTime(String strLocalTime) {
        if (Strings.isNullOrEmpty(strLocalTime)) {
            return null;
        }
        return LocalTime.parse(strLocalTime, TIME_FORMATTER);
    }

    public static Date getYesterdayTime(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DAY_OF_YEAR, -1);
        return ca.getTime();
    }

    public static Date getPrevHours(Date date, int prevHours) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.HOUR_OF_DAY, -prevHours);
        return ca.getTime();
    }

    public static Date getPrevMinutes(Date date, int prevMinutes) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MINUTE, -prevMinutes);
        return ca.getTime();
    }

    public static String getNextTime(Date date, int nextMinutes, String format) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MINUTE, nextMinutes);
        return new SimpleDateFormat(format).format(ca.getTime());
    }

    public static Date getNextDays(Date date, int nextDays) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DAY_OF_YEAR, nextDays);
        return ca.getTime();
    }

    public static Date getNextMinutes(Date date, int nextMinutes) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MINUTE, nextMinutes);
        return ca.getTime();
    }

    /**
     * 获取明天零点整的毫秒数
     */
    public static long getNextZero(long millis) {
        long rawOffset = TimeZone.getDefault().getRawOffset();
        return (millis + rawOffset) / ONE_DAY_MILLIS * ONE_DAY_MILLIS + ONE_DAY_MILLIS - rawOffset;
    }

    /**
     * 检查日期有消息
     *
     * @param source        源日期
     * @param expiresSecond 源日期的有效时长，单位秒
     * @param target        对比目标日期
     * @return true有效、false无效
     */
    public static boolean checkValidDate(Date source, Integer expiresSecond, Date target) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(source);
        ca.add(Calendar.SECOND, expiresSecond);
        return ca.getTime().compareTo(target) >= 0;
    }

    public static boolean checkValidDate(Date source, String beginTime, String endTime) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_FORMAT);
        String time = dateFormat.format(source);
        return time.compareTo(beginTime) >= 0 && time.compareTo(endTime) <= 0;
    }

    public static Date parseTimestamp(Long timestamp) {
        if (timestamp.toString().length() == 13) {
            return new Date(timestamp);
        }
        return new Date(timestamp.intValue() * 1000L);
    }

    public static Date parseTimestamp(String timestamp, String format) {
        try {
            return new SimpleDateFormat(format).parse(timestamp);
        } catch (ParseException e) {
            return null;
        }
    }

    public static Date parseTimestamp(String timestamp, String format, Locale locale) {
        try {
            return new SimpleDateFormat(format, locale).parse(timestamp);
        } catch (ParseException e) {
            return null;
        }
    }

    public static String getToday() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DAY_FORMAT);
        return dateFormat.format(new Date());
    }

    public static String getNow() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DAY_TIME_FORMAT);
        return dateFormat.format(new Date());
    }

    public static String getNowGmtString() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(RFC_2616_DAY_TIME_FORMAT, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(new Date());
    }

    public static String getGmtString(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(RFC_2616_DAY_TIME_FORMAT, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return dateFormat.format(date);
    }

    public static String getTime(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }

    public static String getISO8601Time(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(ISO_8601_DAY_TIME_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.format(date);
    }

    public static String getISO8601Date(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(ISO_8601_DAY_TIME);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.format(date);
    }

    public static String getRFC2616Date(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(RFC_2616_DAY_TIME_PRO_FORMAT, Locale.ENGLISH);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.format(date);
    }

    public static Date parse(String strDate) throws ParseException {
        if (null == strDate || "".equals(strDate)) {
            return null;
        }
        // The format contains 4 '
        if (strDate.length() == ISO_8601_DAY_TIME_FORMAT.length() - 4) {
            return parseISO8601(strDate);
        } else if (strDate.length() == RFC_2616_DAY_TIME_PRO_FORMAT.length()) {
            return parseRFC2616(strDate);
        }
        return null;
    }

    public static Date parseISO8601(String strDate) throws ParseException {
        if (null == strDate || "".equals(strDate)) {
            return null;
        }

        // The format contains 4 ' symbol
        if (strDate.length() != (ISO_8601_DAY_TIME_FORMAT.length() - 4)) {
            return null;
        }

        SimpleDateFormat df = new SimpleDateFormat(ISO_8601_DAY_TIME_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.parse(strDate);
    }

    public static Date parseISO8601Minute(String strDate) throws ParseException {
        if (null == strDate || "".equals(strDate)) {
            return null;
        }

        // The format contains 4 ' symbol
        if (strDate.length() != (ISO_8601_DAY_MINUTE_FORMAT.length() - 4)) {
            return null;
        }

        SimpleDateFormat df = new SimpleDateFormat(ISO_8601_DAY_MINUTE_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.parse(strDate);
    }

    public static Date parseRFC2616(String strDate) throws ParseException {
        if (null == strDate || "".equals(strDate) || strDate.length() != RFC_2616_DAY_TIME_PRO_FORMAT.length()) {
            return null;
        }
        SimpleDateFormat df = new SimpleDateFormat(RFC_2616_DAY_TIME_PRO_FORMAT, Locale.ENGLISH);
        df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
        return df.parse(strDate);
    }

    public static void main(String[] args) {
//        String dateStr = "Thu, 31 May 2018 05:03:18 GMT";
//        Date date = parseTimestamp(dateStr, RFC_2616_DAY_TIME_FORMAT, Locale.US);
//        System.out.println("date = " + date);

//        Long time = 1527095820L;
//        Date d = parseTimestamp(time);
//        System.out.println("d = " + d);

        String raw = "2018-12-26 10:21:17.638";
        Date date = parseTimestamp(raw, DAY_TIME_PRO_FORMAT);
        System.out.println("date: " + date);
    }

}
